package com.flyiu.data.idempotent.aspect;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.flyiu.data.idempotent.annotation.Idempotent;
import com.flyiu.data.idempotent.context.IdempotentUtil;
import com.flyiu.data.idempotent.handler.InempotentInvoke;

/**
 * 
 * <p>创建时间：2017年10月12日 下午3:54:18 类说明 此拦截器要求在分布式事务之前执行，本地事务之后,建议本地事务配置为1000
 * 
 * 经测试，在本地事务之后可能存在性能问题
 * </p>
 *
 * @author flyiu@flyiu.com
 * @version $Id: IdempotentAspect.java, v 0.1 2018年6月30日 上午11:35:08 flyiu Exp $
 */
@Aspect
@Component
@Order(100)
// @ConditionalOnBean(IdempotentConfig.class)
public class IdempotentAspect {
    @Autowired
    private InempotentInvoke invoke;
    
    /**
     * 幂等接口
     */
    @Pointcut("@annotation(com.flyiu.data.idempotent.annotation.Idempotent) || @within(com.flyiu.data.idempotent.annotation.Idempotent) ")
    public void idempotent() {

    }

    @Around("idempotent()")
    public Object doRequest(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Idempotent idempotent = IdempotentUtil.getIdempotentAnnotation(method);
        return invoke.invoke(joinPoint, idempotent);
    }
}
